import type { 
  ChatCompletionRequest, 
  ExecutionStatus, 
  ExecutionLog, 
  Task, 
  TaskModification, 
  MCPService 
} from '@/types'

// API 基础配置
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8080/api/v1'
const API_TIMEOUT = 30000

// 请求拦截器
class APIClient {
  private baseURL: string
  private timeout: number
  private defaultHeaders: Record<string, string>

  constructor(baseURL: string = API_BASE_URL, timeout: number = API_TIMEOUT) {
    this.baseURL = baseURL
    this.timeout = timeout
    this.defaultHeaders = {
      'Content-Type': 'application/json',
      'Accept': 'application/json'
    }
  }

  private async request<T>(
    endpoint: string,
    options: RequestInit = {}
  ): Promise<T> {
    const url = `${this.baseURL}${endpoint}`
    
    const config: RequestInit = {
      ...options,
      headers: {
        ...this.defaultHeaders,
        ...options.headers
      },
      signal: AbortSignal.timeout(this.timeout)
    }

    try {
      const response = await fetch(url, config)
      
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`)
      }

      const contentType = response.headers.get('content-type')
      if (contentType && contentType.includes('application/json')) {
        return await response.json()
      }
      
      return await response.text() as T
    } catch (error) {
      if (error instanceof Error) {
        throw new Error(`API request failed: ${error.message}`)
      }
      throw new Error('Unknown API error')
    }
  }

  async get<T>(endpoint: string, params?: Record<string, any>): Promise<T> {
    const url = new URL(endpoint, this.baseURL)
    if (params) {
      Object.entries(params).forEach(([key, value]) => {
        if (value !== undefined && value !== null) {
          url.searchParams.append(key, String(value))
        }
      })
    }
    
    return this.request<T>(url.pathname + url.search)
  }

  async post<T>(endpoint: string, data?: any): Promise<T> {
    return this.request<T>(endpoint, {
      method: 'POST',
      body: data ? JSON.stringify(data) : undefined
    })
  }

  async put<T>(endpoint: string, data?: any): Promise<T> {
    return this.request<T>(endpoint, {
      method: 'PUT',
      body: data ? JSON.stringify(data) : undefined
    })
  }

  async delete<T>(endpoint: string): Promise<T> {
    return this.request<T>(endpoint, {
      method: 'DELETE'
    })
  }
}

// API 响应格式
interface APIResponse<T> {
  success: boolean
  data?: T
  error?: {
    code: string
    message: string
    details?: any
  }
  message?: string
  timestamp: string
  requestId: string
  path?: string
}

// API 服务类
export class APIService {
  private client: APIClient

  constructor() {
    this.client = new APIClient()
  }

  // 统一问答接口
  async chatCompletions(request: ChatCompletionRequest): Promise<ReadableStream> {
    const response = await fetch(`${API_BASE_URL}/chat/completions`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'text/event-stream'
      },
      body: JSON.stringify(request)
    })

    if (!response.ok) {
      throw new Error(`HTTP ${response.status}: ${response.statusText}`)
    }

    if (!response.body) {
      throw new Error('No response body')
    }

    return response.body
  }

  // 任务管理接口
  async getTasks(sessionId: string): Promise<Task[]> {
    const response = await this.client.get<APIResponse<Task[]>>(`/tasks/${sessionId}`)
    if (!response.success) {
      throw new Error(response.error?.message || 'Failed to get tasks')
    }
    return response.data || []
  }

  async createTask(sessionId: string, task: Omit<Task, 'id' | 'createdAt' | 'updatedAt'>): Promise<Task> {
    const response = await this.client.post<APIResponse<Task>>(`/tasks/${sessionId}`, task)
    if (!response.success) {
      throw new Error(response.error?.message || 'Failed to create task')
    }
    return response.data!
  }

  async updateTask(sessionId: string, taskId: string, updates: Partial<Task>): Promise<Task> {
    const response = await this.client.put<APIResponse<Task>>(`/tasks/${sessionId}/${taskId}`, updates)
    if (!response.success) {
      throw new Error(response.error?.message || 'Failed to update task')
    }
    return response.data!
  }

  async deleteTask(sessionId: string, taskId: string): Promise<void> {
    const response = await this.client.delete<APIResponse<void>>(`/tasks/${sessionId}/${taskId}`)
    if (!response.success) {
      throw new Error(response.error?.message || 'Failed to delete task')
    }
  }

  async modifyTasks(sessionId: string, modification: TaskModification): Promise<Task[]> {
    const response = await this.client.post<APIResponse<Task[]>>(`/tasks/${sessionId}/modify`, modification)
    if (!response.success) {
      throw new Error(response.error?.message || 'Failed to modify tasks')
    }
    return response.data || []
  }

  // 执行控制接口
  async confirmTaskExecution(sessionId: string): Promise<void> {
    const response = await this.client.post<APIResponse<void>>(`/execution/${sessionId}/confirm`)
    if (!response.success) {
      throw new Error(response.error?.message || 'Failed to confirm execution')
    }
  }

  async cancelTaskExecution(sessionId: string): Promise<void> {
    const response = await this.client.post<APIResponse<void>>(`/execution/${sessionId}/cancel`)
    if (!response.success) {
      throw new Error(response.error?.message || 'Failed to cancel execution')
    }
  }

  async pauseTaskExecution(sessionId: string): Promise<void> {
    const response = await this.client.post<APIResponse<void>>(`/execution/${sessionId}/pause`)
    if (!response.success) {
      throw new Error(response.error?.message || 'Failed to pause execution')
    }
  }

  async resumeTaskExecution(sessionId: string): Promise<void> {
    const response = await this.client.post<APIResponse<void>>(`/execution/${sessionId}/resume`)
    if (!response.success) {
      throw new Error(response.error?.message || 'Failed to resume execution')
    }
  }

  // 执行状态查询接口
  async getExecutionStatus(sessionId: string): Promise<ExecutionStatus | null> {
    try {
      const response = await this.client.get<APIResponse<ExecutionStatus>>(`/execution/${sessionId}/status`)
      if (!response.success) {
        return null
      }
      return response.data || null
    } catch (error) {
      console.warn('Failed to get execution status:', error)
      return null
    }
  }

  async getExecutionLogs(sessionId: string, level?: string, limit?: number): Promise<ExecutionLog[]> {
    const params: Record<string, any> = {}
    if (level && level !== 'ALL') params.level = level
    if (limit) params.limit = limit

    try {
      const response = await this.client.get<APIResponse<ExecutionLog[]>>(`/execution/${sessionId}/logs`, params)
      if (!response.success) {
        return []
      }
      return response.data || []
    } catch (error) {
      console.warn('Failed to get execution logs:', error)
      return []
    }
  }

  // MCP 服务管理接口
  async getMCPServices(): Promise<MCPService[]> {
    const response = await this.client.get<APIResponse<MCPService[]>>('/mcp/services')
    if (!response.success) {
      throw new Error(response.error?.message || 'Failed to get MCP services')
    }
    return response.data || []
  }

  async createMCPService(service: Omit<MCPService, 'id' | 'createdAt' | 'updatedAt'>): Promise<MCPService> {
    const response = await this.client.post<APIResponse<MCPService>>('/mcp/services', service)
    if (!response.success) {
      throw new Error(response.error?.message || 'Failed to create MCP service')
    }
    return response.data!
  }

  async updateMCPService(serviceId: string, updates: Partial<MCPService>): Promise<MCPService> {
    const response = await this.client.put<APIResponse<MCPService>>(`/mcp/services/${serviceId}`, updates)
    if (!response.success) {
      throw new Error(response.error?.message || 'Failed to update MCP service')
    }
    return response.data!
  }

  async deleteMCPService(serviceId: string): Promise<void> {
    const response = await this.client.delete<APIResponse<void>>(`/mcp/services/${serviceId}`)
    if (!response.success) {
      throw new Error(response.error?.message || 'Failed to delete MCP service')
    }
  }

  async testMCPService(serviceId: string): Promise<{ success: boolean; responseTime: number; error?: string }> {
    const response = await this.client.post<APIResponse<{ success: boolean; responseTime: number; error?: string }>>(`/mcp/services/${serviceId}/test`)
    if (!response.success) {
      throw new Error(response.error?.message || 'Failed to test MCP service')
    }
    return response.data!
  }

  // 会话管理接口
  async createSession(): Promise<{ sessionId: string }> {
    const response = await this.client.post<APIResponse<{ sessionId: string }>>('/sessions')
    if (!response.success) {
      throw new Error(response.error?.message || 'Failed to create session')
    }
    return response.data!
  }

  async getSession(sessionId: string): Promise<any> {
    const response = await this.client.get<APIResponse<any>>(`/sessions/${sessionId}`)
    if (!response.success) {
      throw new Error(response.error?.message || 'Failed to get session')
    }
    return response.data
  }

  async deleteSession(sessionId: string): Promise<void> {
    const response = await this.client.delete<APIResponse<void>>(`/sessions/${sessionId}`)
    if (!response.success) {
      throw new Error(response.error?.message || 'Failed to delete session')
    }
  }

  // 健康检查
  async healthCheck(): Promise<{ status: string; timestamp: string }> {
    const response = await this.client.get<APIResponse<{ status: string; timestamp: string }>>('/health')
    if (!response.success) {
      throw new Error(response.error?.message || 'Health check failed')
    }
    return response.data!
  }
}

// 单例实例
const apiService = new APIService()

// 组合式 API
export const useAPIService = () => {
  return apiService
}

export default apiService